package com.zang.test;


import java.util.HashMap;
import java.util.Map;

/**
 * 通过编译器测试多线程之间对锁对象的影响（然而并未达到测试目的）
 * Java平台包含两种编译器： 静态编译器 javac,  动态编译器 JIT编译器
 * javac 是将源代码.java编译为字节码.class二进制文件，它是在代码编译期介入的
 * JIT编译器是将java字节码动态编译为java虚拟机宿主主体的本地代码（机器码），它是在java运行过程中介入的
 *
 * JIT指令重排序Demo
 * java -server -XX:-UseCompressedOops com.zang.test.JITReorderingDemo
 * javac -encoding utf-8 JITReorderingDemo.java
 * @author Zhang Qiang
 * 2019/9/11 17:24
 */
//@ConcurrencyTest(iterations = 200000)
public class JITReorderingDemo {

    private int externalData = 1;
    private Helper helper;

    public void createHelper(){
        helper = new Helper(externalData);
    }

    public int sum(){
        int sum = 0;
        final Helper observerHepler = helper;
        if (null == observerHepler){
            sum = -1;
        } else {
          sum = observerHepler.payloadA + observerHepler.payloadB + observerHepler.payloadC + observerHepler.payloadD;
        }
        return sum;
    }

    static class Helper{
        private int payloadA;
        private int payloadB;
        private int payloadC;
        private int payloadD;

        public Helper(){}

        public Helper(int externalData) {
            this.payloadA = externalData;
            this.payloadB = externalData;
            this.payloadC = externalData;
            this.payloadD = externalData;
        }
    }

    private static volatile Integer dSum = 0;
    private static volatile Integer zSum = 0;
    private static volatile Integer sum_1 = 0;
    private static volatile Integer sum_2 = 0;
    private static volatile Integer sum_3 = 0;
    private static volatile Integer sum_4 = 0;

    public static void main(String[] args) throws InterruptedException {
        JITReorderingDemo j = new JITReorderingDemo();
        for (int i=0; i<200000; i++){
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    j.createHelper();
                    int sum = j.sum();
                    switch (sum){
                        case -1:
                            System.out.println("Helper is null, sum: " + sum);
                            dSum ++;
                            break;
                        case 0:
                            System.out.println("Helper is not null, but it is no initialized, sum: " + sum);
                            zSum ++;
                            break;
                        case 1:
                            System.out.println("only 1 filed of Helper instance was initialized, sum: " + sum);
                            sum_1 ++;
                            break;
                        case 2:
                            System.out.println("only 2 filed of Helper instance was initialized, sum: " + sum);
                            sum_2 ++;
                            break;
                        case 3:
                            System.out.println("only 3 filed of Helper instance was initialized, sum: " + sum);
                            sum_3 ++;
                            break;
                        case 4:
                            System.out.println("Helper instance was fully initialized, sum: " + sum);
                            sum_4 ++;
                            break;
                    }

                    System.out.println("dSum:" + dSum +
                            ", zSum:" + zSum +
                            ", sum_1:" + sum_1 +
                            ", sum_2:" + sum_2 +
                            ", sum_3:" + sum_3 +
                            ", sum_4:" + sum_4 +
                            "");
                }
            });
            thread.setName("Thread " + i + "号线程");
            thread.start();
        }

    }

}
